package com.yuyou.train.gateway.filter;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StreamUtils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.yuyou.train.gateway.bean.requestLog;
import com.yuyou.train.util.bean.LoginRedisObj;
import com.yuyou.train.util.bean.ReturnCode;
import com.yuyou.train.util.bean.ReturnResult;

public class LogFilter extends ZuulFilter {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private final List<String> exclusiveList=new ArrayList<String>(
			Arrays.asList("failedInfoExport"));
	
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Override
	public Object run() {
		LoginRedisObj obj = null;
		String jsonObj=StringUtils.EMPTY;
		long traceId = Instant.now().toEpochMilli();
		requestLog log = new requestLog();
		log.setTraceId(traceId);
		try {
			RequestContext ctx = RequestContext.getCurrentContext();
			HttpServletRequest request = ctx.getRequest();
			
			log.setUri(request.getRequestURI());
			log.setParams(request.getParameterMap());
			
			String accessToken = request.getHeader("accessToken");
			if (StringUtils.isEmpty(accessToken)) {
				accessToken = request.getParameter("accessToken");
			}

			if(!StringUtils.isEmpty(accessToken)){
				jsonObj = stringRedisTemplate.opsForValue().get(accessToken);
			}
			if(!StringUtils.isEmpty(jsonObj)){
				obj = JSONObject.parseObject(jsonObj,new TypeReference<LoginRedisObj>() {});
			}			
			log.setPrincipal(StringUtils.isEmpty(accessToken) || obj == null ? "": obj.getUserId());
			
			
			String body = StringUtils.EMPTY;
			InputStream stream = ctx.getResponseDataStream();
			body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
			log.setResp(body);
			ctx.set("isSuccess", true);
			if(StringUtils.isEmpty(body)){
				ReturnResult<String> res=new ReturnResult<String>(false,null,null,ReturnCode.code._3001.getCode(),ReturnCode.code._3001.getMessage());
				body=res.toJsonString();
			}		
			ctx.setResponseBody(body);// 返回错误内容
			ctx.getResponse().setContentType("text/html;charset=UTF-8");

		} catch (Exception e) {
			log.setResp(e.getMessage());
			logger.error(traceId + ":网关日志错误", e);
		}
		logger.info(JSONObject.toJSONString(log, true));
		return null;

	}

	@Override
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext() ;
		HttpServletRequest request = ctx.getRequest() ;
		String uri=request.getRequestURI();
		//登录绕过拦截器
		for(String exUri:exclusiveList){
			if(uri.contains(exUri)){
	            return false;
			}
		}
		return true;
	}

	@Override
	public int filterOrder() {
		return 0;
	}

	@Override
	public String filterType() {
		return "post";
	}

}
